package com.recSystem.Service.ServiceImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.recSystem.Entity.Converters.AuthorConverter;
import com.recSystem.Entity.Converters.PaperConverter;
import com.recSystem.Entity.DO.*;
import com.recSystem.Entity.DTO.*;
import com.recSystem.Entity.DTO.Param.*;
import com.recSystem.Entity.Enum.SearchField;
import com.recSystem.Entity.POJO.HttpResponse;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.recSystem.Mapper.*;
import com.recSystem.Service.PaperService;
import com.recSystem.Service.RecommendService;
import com.recSystem.Utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.client.RestTemplate;


@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, PaperDO> implements PaperService {
    private static final Logger log = LoggerFactory.getLogger(PaperServiceImpl.class);
    private final FavoriteMapper favoriteMapper;
    private final WorkMapper workMapper;
    private final AuthorMapper authorMapper;
    private final RecommendService recommendService;
    private final VersionsMapper versionsMapper;
    private final TagsMapper tagsMapper;
    private final UserMapper userMapper;
    private final InterestMapper interestMapper;
    private final BrowsingMapper browsingMapper;
    private final ReferenceMapper referenceMapper;
    private final CitationMapper citationMapper;

    public PaperServiceImpl(FavoriteMapper favoriteMapper, UserMapper userMapper, TagsMapper tagsMapper, VersionsMapper versionsMapper, WorkMapper workMapper, AuthorMapper authorMapper, RecommendService recommendService, InterestMapper interestMapper, BrowsingMapper browsingMapper, ReferenceMapper referenceMapper, CitationMapper citationMapper) {
        this.favoriteMapper = favoriteMapper;
        this.workMapper = workMapper;
        this.authorMapper = authorMapper;
        this.recommendService = recommendService;
        this.versionsMapper = versionsMapper;
        this.tagsMapper = tagsMapper;
        this.userMapper = userMapper;
        this.interestMapper = interestMapper;
        this.browsingMapper = browsingMapper;
        this.referenceMapper = referenceMapper;
        this.citationMapper = citationMapper;
    }

    // 在paper表中将paper_id转化为id字段
    public String getArxivIdFromPaperId(int paper_id){
        PaperDO paperDO = baseMapper.selectById(paper_id);
        String arxiv_id = paperDO.getId();
        return arxiv_id;
    }

    // 在paper表中将id转化为paper_id字段
    public int getPaperIdFromArxivId(String arxiv_id){
        QueryWrapper<PaperDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", arxiv_id);
        PaperDO paperDO = baseMapper.selectOne(queryWrapper);
        if(paperDO != null){
            int paper_id = paperDO.getPaperId();
            return paper_id;
        }
        return -1;
    }

    // *******高级检索论文
    public HttpResponse<NewPaperSearchDTO> advancedSearchPaper(PaperAdvancedSearchParam param, String token) {
        Integer userId = TokenParser.parse(token);
        // 逻辑运算
        String operator2 = param.getOperator2();
        String operator3 = param.getOperator3();
        String operator4 = param.getOperator4();
        // 检索字段
        String field1 = param.getField1();
        String field2 = param.getField2();
        String field3 = param.getField3();
        String field4 = param.getField4();
        // 检索字
        String query1 = param.getQuery1();
        String query2 = param.getQuery2();
        String query3 = param.getQuery3();
        String query4 = param.getQuery4();
        // 一页最大值
        int maxLength = param.getMaxLength();
        // 第几页
        int offset = param.getOffset();
        // 排序
        String sortField = param.getSort();
        // 学科限定
        List<String> tagsChecked = param.getTagsChecked();
        // 时间限定
        String startDate = param.getStartDate();
        String endDate = param.getEndDate();
        return null;
    }

    // 模糊搜索论文
    public HttpResponse<NewPaperSearchDTO> searchPaper(PaperSearchParam param, String token) {
        Integer userId = TokenParser.parse(token);
        // 查询关键字
        String query = param.getQuery();
        // 一页最大值
        int maxLength = param.getMaxLength();
        // 第几页
        int offset = param.getOffset();
        // 在哪个字段搜索
        String searchField = param.getField();
        // 依据哪个字段排序
        String sortField = param.getSort();
        // 标签列表
        List<String> tagsChecked = param.getTagsChecked();
        // 获取时间
        String startDate = param.getStartDate();
        String endDate = param.getEndDate();

        try {
            // 获取收藏
            QueryWrapper<PaperDO> qw = new QueryWrapper<>();
            qw.orderByDesc("update_date");

            if (query.equals("") || searchField.equals(SearchField.title.getSearchField())
                    || searchField.equals(SearchField.abs.getSearchField())) {
                if (searchField.equals(SearchField.title.getSearchField())) {
                    qw.like(SearchField.title.getDbField(), query);
                } else if (searchField.equals(SearchField.abs.getSearchField())) {
                    qw.like(SearchField.abs.getDbField(), query);
                }
                // 判断是否带标签
                if (!tagsChecked.isEmpty()) {
                    for (String a : tagsChecked) {
                        qw.like("categories", a);
                    }
                }
                // 判断是否有起始时间限制
                if (startDate != null && endDate != null && !startDate.equals("") && !endDate.equals("")) {
                    qw.between("update_date", startDate, endDate);
                }
            } else if (searchField.equals(SearchField.author.getSearchField())) {
                List<Integer> autherlist = new ArrayList<>();

                List<AuthorDO> authorDOS = authorMapper.selectList(new QueryWrapper<AuthorDO>().
                        like(SearchField.author.getDbField(), query));

                List<AuthorDTO> authorDTOS = new ArrayList<>();
                assert authorDOS != null;
                int all = 0;
                for (AuthorDO temp : authorDOS) {
                    String total = new String();
                    if (temp.getTotal() != null && !temp.getTotal().equals("")) {
                        String[] strArr = temp.getTotal().split(" ");
                        total = strArr[0];
                        all = Integer.valueOf(total);
                    }
                    AuthorDTO authorDTO = new AuthorDTO(temp.getAuthorId(), temp.getAuthorName(), all);
                    authorDTOS.add(authorDTO);
                }
                NewPaperSearchDTO paperSearchDTO = new NewPaperSearchDTO(authorDOS.size(), null, authorDTOS);

                return new HttpResponse<>(new StatusDTO(Constant.SUC_CODE, "查询成功"), paperSearchDTO);
            }
            // 分页
            Page<PaperDO> page = new Page<>(offset, (maxLength != 0) ? maxLength : 10);
            Page<PaperDO> paperDOPage = baseMapper.selectPage(page, qw);
            List<PaperDO> records = paperDOPage.getRecords();
            assert records != null;
            List<PaperAllDo> paperAllDos = new ArrayList<>();

            for (PaperDO temp : records) {
                Integer id = temp.getPaperId();
                // 获取最新版本
                QueryWrapper<VersionDO> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("paper_id", id);
                List<VersionDO> versionDO = versionsMapper.selectList(queryWrapper);
                // 获取长度
                int len = versionDO.size();
                // 取出最大的版本号
                String a = versionDO.get(0).getVersion();
                for (VersionDO t : versionDO) {

                    int result = t.getVersion().compareTo(a);
                    if (result > 0) {
                        a = t.getVersion();
                    }
                }

                QueryWrapper<WorkDO> workDOQueryWrapper = new QueryWrapper<>();
                // 设置查询条件
                workDOQueryWrapper.eq("paper_id", id);
                List<WorkDO> workDOS = workMapper.selectList(workDOQueryWrapper);
                List<Integer> authorIds = workDOS.stream()
                        .map(WorkDO::getAuthorId)
                        .collect(Collectors.toList());
                QueryWrapper<AuthorDO> authorDOQueryWrapper = new QueryWrapper<>();
                // 设置查询条件
                authorDOQueryWrapper.in("author_id", authorIds);
                List<AuthorDO> authorDOS = authorMapper.selectList(authorDOQueryWrapper);

                List<AuthorDTO> authorDTOS = new ArrayList<>();
                for (AuthorDO authorDO : authorDOS) {
                    AuthorDTO authorDTO = new AuthorDTO(authorDO.getAuthorId(), authorDO.getAuthorName(), null);
                    authorDTOS.add(authorDTO);
                }
                boolean fa = false;
                QueryWrapper<FavoriteDO> qw1 = new QueryWrapper<>();
                qw1.eq("paper_id", id);
                qw1.eq("user_id", userId);
                long count = favoriteMapper.selectCount(qw1);

                if (!String.valueOf(count).equals("0")) {
                    fa = true;
                }
                // 汇总一下
                PaperAllDo paperAllDo = new PaperAllDo(temp.getPaperId(), temp.getTitle(), authorDTOS, temp.getUpdateDate(), temp.getPaperAbstract(), temp.getJournalRef(),temp.getComments(), temp.getCategories().split(" "), temp.getUrl(), a, temp.getDoi(), fa);
                paperAllDos.add(paperAllDo);
            }
            int aaa = new Long(paperDOPage.getTotal()).intValue();
            NewPaperSearchDTO paperSearchDTO = new NewPaperSearchDTO(aaa, paperAllDos, null);
            return new HttpResponse<>(new StatusDTO(Constant.SUC_CODE, "查询成功"), paperSearchDTO);

        } catch (Exception e) {
            // 如果查不到
            e.printStackTrace();
            return new HttpResponse<>(new StatusDTO(Constant.SUC_CODE, "查询失败"), new NewPaperSearchDTO(0, null, null));
        }
    }

    // 每一页的右边界下标
    public int findRightBound(int current, int size, int paperCount) {
        int rightBound = 0;
        if (size * current > paperCount) {
            rightBound = paperCount;
        } else {
            rightBound = size * current;
        }
        return rightBound;
    }

    // 生成关键词云
    public HttpResponse generatePaperKeywords(PaperIdParam param, String token) {
        int paperId = param.getPaperId();
        PaperDO paperDO = baseMapper.selectById(paperId);

        // 根据作者发表论文的分类、标题为基础数据，再利用YAKE分析其研究兴趣
        StringBuffer text = new StringBuffer();
        // 创建一个映射，将分类的简称和全称一一对应
        HashMap<String, String> catMap = new HashMap<>();
        catMap.put("cs.AI", "Artificial Intelligence of Computer Science");
        catMap.put("cs.AR", "Hardware Architecture of Computer Science");
        catMap.put("cs.CC", "Computational Complexity of Computer Science");
        catMap.put("cs.CE", "Computational Engineering, Finance, and Science of Computer Science");
        catMap.put("cs.CG", "Computational Geometry of Computer Science");
        catMap.put("cs.CL", "Computation and Language of Computer Science");
        catMap.put("cs.CR", "Cryptography and Security of Computer Science");
        catMap.put("cs.CV", "Computer Vision and Pattern Recognition of Computer Science");
        catMap.put("cs.CY", "Computers and Society of Computer Science");
        catMap.put("cs.DB", "Databases in Computer Science of Computer Science");
        catMap.put("cs.DC", "Distributed, Parallel, and Cluster Computing in Computer Science of Computer Science");
        catMap.put("cs.DL", "Digital Libraries of Computer Science");
        catMap.put("cs.DM", "Discrete Mathematics of Computer Science");
        catMap.put("cs.DS", "Data Structures and Algorithms of Computer Science");
        catMap.put("cs.ET", "Emerging Technologies of Computer Science");
        catMap.put("cs.FL", "Formal Languages and Automata Theory of Computer Science");
        catMap.put("cs.GL", "General Literature of Computer Science");
        catMap.put("cs.GR", "Graphics of Computer Science");
        catMap.put("cs.GT", "Computer Science and Game Theory of Computer Science");
        catMap.put("cs.HC", "Human-Computer Interaction of Computer Science");
        catMap.put("cs.IR", "Information Retrieval of Computer Science");
        catMap.put("cs.IT", "Information Theory of Computer Science");
        catMap.put("cs.LG", "Machine Learning of Computer Science");
        catMap.put("cs.LO", "Logic in Computer Science of Computer Science");
        catMap.put("cs.MA", "Multiagent Systems of Computer Science");
        catMap.put("cs.MM", "Multimedia of Computer Science");
        catMap.put("cs.MS", "Mathematical Software of Computer Science");
        catMap.put("cs.NA", "Numerical Analysis of Computer Science");
        catMap.put("cs.NE", "Neural and Evolutionary Computing of Computer Science");
        catMap.put("cs.NI", "Networking and Internet Architecture of Computer Science");
        catMap.put("cs.OH", "Other Computer Science of Computer Science");
        catMap.put("cs.OS", "Operating Systems of Computer Science");
        catMap.put("cs.PF", "Performance of Computer Science");
        catMap.put("cs.PL", "Programming Languages of Computer Science");
        catMap.put("cs.RO", "Robotics of Computer Science");
        catMap.put("cs.SC", "Symbolic Computation of Computer Science");
        catMap.put("cs.SD", "Sound of Computer Science");
        catMap.put("cs.SE", "Software Engineering of Computer Science");
        catMap.put("cs.SI", "Social and Information Networks of Computer Science");
        catMap.put("cs.SY", "Systems and Control of Computer Science");
        catMap.put("econ.EM", "Econometrics of Econometrics");
        catMap.put("econ.GN", "General Economics of Econometrics");
        catMap.put("econ.TH", "Theoretical Economics of Econometrics");
        catMap.put("eess.AS", "Audio and Speech Processing of Electrical Engineering and Systems Science");
        catMap.put("eess.IV", "Image and Video Processing of Electrical Engineering and Systems Science");
        catMap.put("eess.SP", "Signal Processing of Electrical Engineering and Systems Science");
        catMap.put("eess.SY", "Systems and Control of Electrical Engineering and Systems Science");
        catMap.put("math.AC", "Commutative Algebra of Mathematics");
        catMap.put("math.AG", "Algebraic Geometry of Mathematics");
        catMap.put("math.AP", "Analysis of PDEs of Mathematics");
        catMap.put("math.AT", "Algebraic Topology of Mathematics");
        catMap.put("math.CA", "Classical Analysis and ODEs of Mathematics");
        catMap.put("math.CO", "Combinatorics of Mathematics");
        catMap.put("math.CT", "Category Theory of Mathematics");
        catMap.put("math.CV", "Complex Variables of Mathematics");
        catMap.put("math.DG", "Differential Geometry of Mathematics");
        catMap.put("math.DS", "Dynamical Systems of Mathematics");
        catMap.put("math.FA", "Functional Analysis of Mathematics");
        catMap.put("math.GM", "General Mathematics of Mathematics");
        catMap.put("math.GN", "General Topology of Mathematics");
        catMap.put("math.GR", "Group Theory of Mathematics");
        catMap.put("math.GT", "Geometric Topology of Mathematics");
        catMap.put("math.HO", "History and Overview of Mathematics");
        catMap.put("math.IT", "Information Theory of Mathematics");
        catMap.put("math.KT", "K-Theory and Homology of Mathematics");
        catMap.put("math.LO", "Logic of Mathematics");
        catMap.put("math.MG", "Metric Geometry of Mathematics");
        catMap.put("math.MP", "Mathematical Physics of Mathematics");
        catMap.put("math.NA", "Numerical Analysis of Mathematics");
        catMap.put("math.NT", "Number Theory of Mathematics");
        catMap.put("math.OA", "Operator Algebras of Mathematics");
        catMap.put("math.OC", "Optimization and Control of Mathematics");
        catMap.put("math.PR", "Probability of Mathematics");
        catMap.put("math.QA", "Quantum Algebra of Mathematics");
        catMap.put("math.RA", "Rings and Algebras of Mathematics");
        catMap.put("math.RT", "Representation Theory of Mathematics");
        catMap.put("math.SG", "Symplectic Geometry of Mathematics");
        catMap.put("math.SP", "Spectral Theory of Mathematics");
        catMap.put("math.ST", "Statistics Theory of Mathematics");
        catMap.put("astro-ph.CO", "Cosmology and Nongalactic Astrophysics of Astrophysics in Physics");
        catMap.put("astro-ph.EP", "Earth and Planetary Astrophysics of Astrophysics in Physics");
        catMap.put("astro-ph.GA", "Astrophysics of Galaxies of Astrophysics in Physics");
        catMap.put("astro-ph.HE", "High Energy Astrophysical Phenomena of Astrophysics in Physics");
        catMap.put("astro-ph.IM", "Instrumentation and Methods for Astrophysics of Astrophysics in Physics");
        catMap.put("astro-ph.SR", "Solar and Stellar Astrophysics of Astrophysics in Physics");
        catMap.put("cond-mat.dis-nn", "Disordered Systems and Neural Networks of Condensed matter in Physics");
        catMap.put("cond-mat.mes-hall", "Mesoscale and Nanoscale Physics of Condensed matter in Physics");
        catMap.put("cond-mat.mtrl-sci", "Materials Science of Condensed Matter in Physics");
        catMap.put("cond-mat.other", "Other Condensed Matter of Condensed Matter in Physics");
        catMap.put("cond-mat.quant-gas", "Quantum Gases of Condensed Matter in Physics");
        catMap.put("cond-mat.soft", "Soft Condensed Matter of Condensed Matter in Physics");
        catMap.put("cond-mat.stat-mech", "Statistical Mechanics of Condensed Matter in Physics");
        catMap.put("cond-mat.str-el", "Strongly Correlated Electrons of Condensed Matter in Physics");
        catMap.put("cond-mat.supr-con", "Superconductivity of Condensed Matter in Physics");
        catMap.put("gr-qc", "General Relativity and Quantum Cosmology in Physics");
        catMap.put("hep-ex", "High Energy Physics - Experiment in Physics");
        catMap.put("hep-lat", "High Energy Physics - Lattice in Physics");
        catMap.put("hep-ph", "High Energy Physics - Phenomenology in Physics");
        catMap.put("hep-th", "High Energy Physics - Theory in Physics");
        catMap.put("math-ph", "Mathematical Physics in Physics");
        catMap.put("nlin.AO", "Adaptation and Self-Organizing Systems of Nonlinear Sciences in Physics");
        catMap.put("nlin.CD", "Chaotic Dynamics of Nonlinear Sciences in Physics");
        catMap.put("nlin.CG", "Cellular Automata and Lattice Gases of Nonlinear Sciences in Physics");
        catMap.put("nlin.PS", "Pattern Formation and Solitons of Nonlinear Sciences in Physics");
        catMap.put("nlin.SI", "Exactly Solvable and Integrable Systems of Nonlinear Sciences in Physics");
        catMap.put("nucl-ex", "Nuclear Experiment in Physics");
        catMap.put("nucl-th", "Nuclear Theory in Physics");
        catMap.put("physics.acc-ph", "Accelerator Physics in Physics");
        catMap.put("physics.ao-ph", "Atmospheric and Oceanic Physics in Physics");
        catMap.put("physics.app-ph", "Applied Physics in Physics");
        catMap.put("physics.atm-clus", "Atomic and Molecular Clusters in Physics");
        catMap.put("physics.atom-ph", "Atomic Physics in Physics");
        catMap.put("physics.bio-ph", "Biological Physics in Physics");
        catMap.put("physics.chem-ph", "Chemical Physics in Physics");
        catMap.put("physics.class-ph", "Classical Physics in Physics");
        catMap.put("physics.comp-ph", "Computational Physics in Physics");
        catMap.put("physics.data-an", "Data Analysis, Statistics and Probability in Physics");
        catMap.put("physics.ed-ph", "Physics Education in Physics");
        catMap.put("physics.flu-dyn", "Fluid Dynamics in Physics");
        catMap.put("physics.gen-ph", "General Physics in Physics");
        catMap.put("physics.geo-ph", "Geophysics in Physics");
        catMap.put("physics.hist-ph", "History and Philosophy of Physics in Physics");
        catMap.put("physics.ins-det", "Instrumentation and Detectors in Physics");
        catMap.put("physics.med-ph", "Medical Physics in Physics");
        catMap.put("physics.optics", "Optics in Physics");
        catMap.put("physics.plasm-ph", "Plasma Physics in Physics");
        catMap.put("physics.pop-ph", "Popular Physics in Physics");
        catMap.put("physics.soc-ph", "Physics and Society in Physics");
        catMap.put("physics.space-ph", "Space Physics in Physics");
        catMap.put("quant-ph", "Quantum Physics in Physics");
        catMap.put("q-bio.BM", "Biomolecules of Quantitative Biology");
        catMap.put("q-bio.CB", "Cell Behavior of Quantitative Biology");
        catMap.put("q-bio.GN", "Genomics of Quantitative Biology");
        catMap.put("q-bio.MN", "Molecular Networks of Quantitative Biology");
        catMap.put("q-bio.NC", "Neurons and Cognition of Quantitative Biology");
        catMap.put("q-bio.OT", "Other Quantitative Biology of Quantitative Biology");
        catMap.put("q-bio.PE", "Populations and Evolution of Quantitative Biology");
        catMap.put("q-bio.QM", "Quantitative Methods of Quantitative Biology");
        catMap.put("q-bio.SC", "Subcellular Processes of Quantitative Biology");
        catMap.put("q-bio.TO", "Tissues and Organs of Quantitative Biology");
        catMap.put("q-fin.CP", "Computational Finance of Quantitative Finance");
        catMap.put("q-fin.EC", "Economics of Quantitative Finance");
        catMap.put("q-fin.GN", "General Finance of Quantitative Finance");
        catMap.put("q-fin.MF", "Mathematical Finance of Quantitative Finance");
        catMap.put("q-fin.PM", "Portfolio Management of Quantitative Finance");
        catMap.put("q-fin.PR", "Pricing of Securities of Quantitative Finance");
        catMap.put("q-fin.RM", "Risk Management of Quantitative Finance");
        catMap.put("q-fin.ST", "Statistical Finance of Quantitative Finance");
        catMap.put("q-fin.TR", "Trading and Market Microstructure of Quantitative Finance");
        catMap.put("stat.AP", "Applications of Statistics");
        catMap.put("stat.CO", "Computation of Statistics");
        catMap.put("stat.ME", "Methodology of Statistics");
        catMap.put("stat.ML", "Machine Learning of Statistics");
        catMap.put("stat.OT", "Other Statistics of Statistics");
        catMap.put("stat.TH", "Statistics Theory of Statistics");

        // 将特征数据拼接成一个字符串，根据YAKE原理，分类比较重要放前面，标题放后面
        String[] cats = paperDO.getCategories().split(" ");
        // 遍历分类简称数组，转换为全称
        for (String cat : cats) {
            // 检查映射中是否存在对应的全称
            if (catMap.containsKey(cat)) {
                String catDetail = catMap.get(cat);
                text.append(catDetail).append(", ");
            } else {
                text.append(cat).append(", ");
            }
        }
        text.append(paperDO.getTitle()).append(", ").append(paperDO.getPaperAbstract());
        try {
            String exe = "D:\\Python\\venv\\Scripts\\python.exe";
            String py = "D:\\Python\\theOne\\get_paperKeywords.py";
            String [] my_args = new String[] {exe, py, text.toString()};
            Process proc = Runtime.getRuntime().exec(my_args);//执行脚本
            //用输入输出流来截取结果
//            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
//            String line = null;
//            while((line = reader.readLine()) != null){
//                System.out.println(line);
//            }
//            reader.close();
            proc.waitFor();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return new HttpResponse(new StatusDTO(0, "关键词云生成成功"), null);
    }

    // 获取引文网络中的引证文献
    // 根据论文在arxiv中对应的id值调用Semantic Scholar API获取引证文献
    public HttpResponse<List<PaperCiteNetDTO>> getCitations(ArxivIdParam param, String token) {
        // 待返回列表
        List<PaperCiteNetDTO> paperCiteNetDTOList = new ArrayList<>();

        // 1 首先在本地数据库的cite表中查询
        // 1.1 传入的参数是论文的ArxivId，先转化为paper_id
        String arxiv_id = param.getId();
        int paper_id = getPaperIdFromArxivId(arxiv_id);
        // 1.2 根据paper_id在cite表中查询存在
        QueryWrapper<CitationDO> qw = new QueryWrapper<>();
        qw.eq("paper_id", paper_id);
        boolean exist = citationMapper.exists(qw);

        if(exist){
            // 2 若本地数据库中存在直接从本地获取数据
            List<CitationDO> cites = citationMapper.selectList(qw);
            for (int i = 0; i < cites.size(); i++) {
                PaperCiteNetDTO paperCiteNetDTO = new PaperCiteNetDTO();
                CitationDO cite = cites.get(i);
                paperCiteNetDTO.setCite_id(cite.getCiteId());
                paperCiteNetDTO.setTitle(cite.getTitle());
                paperCiteNetDTO.setAuthors(cite.getAuthors());
                paperCiteNetDTO.setJournal(cite.getJournal());
                paperCiteNetDTO.setDate(cite.getDate());
                paperCiteNetDTOList.add(paperCiteNetDTO);
            }
        }else {
            List<CitationDO> citationDOList = new ArrayList<>();
            // 3 若不存在则调用Semantic Scholar API获取，同时*******把数据存储到数据库中********
            // Spring的RestTemplate类提供了发送HTTP请求的简便方法，可以轻松处理常见的GET、POST等请求
            // 创建HttpHeaders对象并设置自定义header
            HttpHeaders headers = new HttpHeaders();
            headers.set("x-api-key", "Jr4YvornaD9nW9vzHAaPB1nU3yGDDB121l5ce65U");
            // 将headers作为HttpEntity的一部分发送请求
            HttpEntity<String> entity = new HttpEntity<>(headers);
            // 拼接URL
            String arXivId = param.getId();
            // fields获取更详细的信息，limit最大值为1000，一次get请求即可获取所需数据！！！！！！！！
            String url = "https://api.semanticscholar.org/graph/v1/paper/ARXIV:" + arXivId + "/citations?fields=title,authors,journal,year,externalIds&limit=1000";
            // 发送请求并获取响应，
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
            // 获取状态码
            HttpStatus statusCode = responseEntity.getStatusCode();
            // 判断状态码是否为成功状态码（200）
            if (statusCode == HttpStatus.OK) {
                // 请求成功，处理响应数据
                String responseBody = responseEntity.getBody();
                System.out.println("引证文献数据为:"+responseBody);
                // 将JSON字符串解析为JSONObject对象
                JSONObject jsonObject = JSON.parseObject(responseBody);
                // 获取"data"字段的值，即包含引证文献信息的数组
                JSONArray citeArray = jsonObject.getJSONArray("data");
                // 遍历数组，获取每个元素中的值
                for (int i = 0; i < citeArray.size(); i++) {
                    PaperCiteNetDTO paperCiteNetDTO = new PaperCiteNetDTO();
                    JSONObject cite = citeArray.getJSONObject(i).getJSONObject("citingPaper");
                    // arxivId判空（****很有必要，虽然论文是来自arxiv的，但是引证文献不一定存在于arxiv数据集中）
                    JSONObject externalIds = cite.getJSONObject("externalIds");
                    if(externalIds != null && externalIds.containsKey("ArXiv")){
                        String arxivId = externalIds.getString("ArXiv");
                        // 数据关联实现链接跳转，************这里涉及select可能影响性能
                        int cite_id = getPaperIdFromArxivId(arxivId);
                        // *****由于目前数据不全可能导致getPaperIdFromArxivId返回值为-1，所以这里做了判空处理，实际这种情况大概率不会发生
                        if(cite_id != -1){
                            paperCiteNetDTO.setCite_id(cite_id);
                        }
                    }
                    // journal判空：注意venue为空字符串""，journal为null
                    if (cite.get("journal") != null) {
                        String journal = cite.getJSONObject("journal").getString("name");
                        paperCiteNetDTO.setJournal(journal);
                    }

                    JSONArray authorArray = cite.getJSONArray("authors");
                    StringBuilder authors = new StringBuilder();
                    // 最多记录6个作者，防止数据过长发生截断报错
                    for (int j = 0; j < Math.min(authorArray.size(), 6); j++) {
                        JSONObject author = authorArray.getJSONObject(j);
                        authors.append(author.getString("name")).append(";");
                    }
                    if (authors.length() > 0) {
                        authors.deleteCharAt(authors.length() - 1);
                        paperCiteNetDTO.setAuthors(authors.toString());
                    }

                    if(cite.getInteger("year")!=null){
                        String year = String.valueOf(cite.getInteger("year"));
                        paperCiteNetDTO.setDate(year);
                    }

                    String title = cite.getString("title");
                    paperCiteNetDTO.setTitle(title);

                    paperCiteNetDTOList.add(paperCiteNetDTO);

                    // ******把数据存储到数据库中
                    CitationDO citationDO = new CitationDO(0, paper_id, title, paperCiteNetDTO.getAuthors(), paperCiteNetDTO.getJournal(), paperCiteNetDTO.getDate(), paperCiteNetDTO.getCite_id());
                    citationDOList.add(citationDO);
//                        citationMapper.insert(citationDO);
                }
            }
            for (int i = 0; i < citationDOList.size(); i++) {
                CitationDO cur = citationDOList.get(i);
                citationMapper.insert(cur);
            }
        }
        return new HttpResponse<>(new StatusDTO(0, "获取引文网络中的引证文献信息成功"), paperCiteNetDTOList);
    }

    // 论文可视化模块相关文献推荐返回假数据
    public HttpResponse<List<PaperCiteNetDTO>> mock_rec(ArxivIdParam param, String token) {
        // 待返回列表
        List<PaperCiteNetDTO> paperCiteNetDTOList = new ArrayList<>();

        QueryWrapper<PaperDO> qw = new QueryWrapper<>();
        qw.like("title", "Neural Network"); // 使用 like 查询 title 中包含 "Neural Network" 的记录
        qw.orderByDesc("update_date"); // 按照 update_date 降序排序
        qw.last("LIMIT 20"); // 限制结果数量为 20 条
        List<PaperDO> mock_rec_papers = baseMapper.selectList(qw);
        for (int i = 0; i < mock_rec_papers.size(); i++) {
            PaperCiteNetDTO paperCiteNetDTO = new PaperCiteNetDTO();
            PaperDO mock_rec_paper = mock_rec_papers.get(i);

            QueryWrapper<WorkDO> workDOQueryWrapper = new QueryWrapper<>();
            // 设置查询条件
            workDOQueryWrapper.eq("paper_id", mock_rec_paper.getPaperId());
            List<WorkDO> workDOS = workMapper.selectList(workDOQueryWrapper);
            List<Integer> authorIds = workDOS.stream()
                    .map(WorkDO::getAuthorId)
                    .collect(Collectors.toList());
            QueryWrapper<AuthorDO> authorDOQueryWrapper = new QueryWrapper<>();
            // 设置查询条件
            authorDOQueryWrapper.in("author_id", authorIds);
            List<AuthorDO> authorDOS = authorMapper.selectList(authorDOQueryWrapper);
            StringBuilder authors = new StringBuilder();
            for (AuthorDO authorDO : authorDOS) {
                authors.append(authorDO.getAuthorName()).append(";");
            }
            authors.deleteCharAt(authors.length() - 1);

            paperCiteNetDTO.setCite_id(mock_rec_paper.getPaperId());
            paperCiteNetDTO.setTitle(mock_rec_paper.getTitle());
            paperCiteNetDTO.setAuthors(authors.toString());
            paperCiteNetDTO.setJournal(mock_rec_paper.getJournalRef());
            paperCiteNetDTO.setDate(mock_rec_paper.getUpdateDate());
            paperCiteNetDTOList.add(paperCiteNetDTO);
        }
        return new HttpResponse<>(new StatusDTO(0, "获取论文可视化模块相关文献推荐的假数据成功"), paperCiteNetDTOList);
    }

    // 获取引文网络中的参考文献
    // 根据论文在arxiv中对应的id值调用Semantic Scholar API获取参考文献
    public HttpResponse<List<PaperCiteNetDTO>> getReferences(ArxivIdParam param, String token) {
        // 待返回列表
        List<PaperCiteNetDTO> paperCiteNetDTOList = new ArrayList<>();

        // 1 首先在本地数据库的ref表中查询
        // 1.1 传入的参数是论文的ArxivId，先转化为paper_id
        int paper_id = getPaperIdFromArxivId(param.getId());
        // 1.2 根据paper_id在ref表中查询存在
        QueryWrapper<ReferenceDO> qw = new QueryWrapper<>();
        qw.eq("paper_id", paper_id);
        boolean exist = referenceMapper.exists(qw);

        if(exist){
            // 2 若本地数据库中存在直接从本地获取数据
            List<ReferenceDO> refs = referenceMapper.selectList(qw);
            for (int i = 0; i < refs.size(); i++) {
                PaperCiteNetDTO paperCiteNetDTO = new PaperCiteNetDTO();
                ReferenceDO ref = refs.get(i);
                paperCiteNetDTO.setCite_id(ref.getRefId());
                paperCiteNetDTO.setTitle(ref.getTitle());
                paperCiteNetDTO.setAuthors(ref.getAuthors());
                paperCiteNetDTO.setJournal(ref.getJournal());
                paperCiteNetDTO.setDate(ref.getDate());
                paperCiteNetDTOList.add(paperCiteNetDTO);
            }
        }else {
            List<ReferenceDO> referenceDOList = new ArrayList<>();
            // 3 若不存在则调用Semantic Scholar API获取，同时*******把数据存储到数据库中********
            // Spring的RestTemplate类提供了发送HTTP请求的简便方法，可以轻松处理常见的GET、POST等请求
            // 创建HttpHeaders对象并设置自定义header
            HttpHeaders headers = new HttpHeaders();
            headers.set("x-api-key", "Jr4YvornaD9nW9vzHAaPB1nU3yGDDB121l5ce65U");
            // 将headers作为HttpEntity的一部分发送请求
            HttpEntity<String> entity = new HttpEntity<>(headers);
            // 拼接URL
            String arXivId = param.getId();
            // fields获取更详细的信息，limit最大值为1000，一次get请求即可获取所需数据！！！！！！！！
            String url = "https://api.semanticscholar.org/graph/v1/paper/ARXIV:" + arXivId + "/references?fields=title,authors,journal,year,externalIds&limit=1000";
            // 发送请求并获取响应，
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
            // 获取状态码
            HttpStatus statusCode = responseEntity.getStatusCode();

            // 判断状态码是否为成功状态码（200）
            if (statusCode == HttpStatus.OK) {
                // 请求成功，处理响应数据
                String responseBody = responseEntity.getBody();
                System.out.println("参考文献数据为:"+responseBody);
                // 将JSON字符串解析为JSONObject对象
                JSONObject jsonObject = JSON.parseObject(responseBody);
                // 获取"data"字段的值，即包含参考文献信息的数组
                JSONArray refArray = jsonObject.getJSONArray("data");

                // 遍历数组，获取每个元素中的值
                for (int i = 0; i < refArray.size(); i++) {
                    PaperCiteNetDTO paperCiteNetDTO = new PaperCiteNetDTO();
                    JSONObject ref = refArray.getJSONObject(i).getJSONObject("citedPaper");
                    // arxivId判空（****很有必要，虽然论文是来自arxiv的，但是参考文献不一定存在于arxiv数据集中）
                    JSONObject externalIds = ref.getJSONObject("externalIds");
                    if(externalIds != null && externalIds.containsKey("ArXiv")){
                        String arxivId = externalIds.getString("ArXiv");
                        int cite_id = getPaperIdFromArxivId(arxivId);
                        // *****由于目前数据不全可能导致getPaperIdFromArxivId返回值为0，所以这里做了判空处理，实际这种情况大概率不会发生
                        if(cite_id != -1){
                            paperCiteNetDTO.setCite_id(cite_id);
                        }
                    }
                    // journal判空：注意venue为空字符串""，journal为null
                    if (ref.get("journal") != null) {
                        String journal = ref.getJSONObject("journal").getString("name");
                        paperCiteNetDTO.setJournal(journal);
                    }

                    JSONArray authorArray = ref.getJSONArray("authors");
                    StringBuilder authors = new StringBuilder();
                    // 最多记录6个作者，防止数据过长发生截断报错
                    for (int j = 0; j < Math.min(authorArray.size(), 6); j++) {
                        JSONObject author = authorArray.getJSONObject(j);
                        authors.append(author.getString("name")).append(";");
                    }
                    if (authors.length() > 0) {
                        authors.deleteCharAt(authors.length() - 1);
                        paperCiteNetDTO.setAuthors(authors.toString());
                    }

                    if(ref.getInteger("year") != null){
                        String year = String.valueOf(ref.getInteger("year"));
                        paperCiteNetDTO.setDate(year);
                    }

                    String title = ref.getString("title");
                    paperCiteNetDTO.setTitle(title);

                    paperCiteNetDTOList.add(paperCiteNetDTO);

                    // ******把数据存储到数据库中
                    ReferenceDO referenceDO = new ReferenceDO(0, paper_id, title, paperCiteNetDTO.getAuthors(), paperCiteNetDTO.getJournal(), paperCiteNetDTO.getDate(), paperCiteNetDTO.getCite_id());
                    referenceDOList.add(referenceDO);
                }
            }
            for (int i = 0; i < referenceDOList.size(); i++) {
                ReferenceDO cur = referenceDOList.get(i);
                referenceMapper.insert(cur);
            }
        }
        return new HttpResponse<>(new StatusDTO(0, "获取引文网络中的参考文献信息成功"), paperCiteNetDTOList);
    }

    // 根据作者id获取发表论文情况
    public HttpResponse<AuthorInfoDTO> getPapersByAuthorId(AuthorInfoParam param, String token) {
        int authorId = param.getAuthorId();
        int userId = TokenParser.parse(token);

        AuthorDO authorDO = authorMapper.selectById(authorId);
        AuthorDTO authorDTO = new AuthorDTO(authorDO.getAuthorId(), authorDO.getAuthorName(), null);

        HashMap<String, Integer> queryMap = new HashMap<>(2);
        queryMap.put("user_id", userId);
        queryMap.put("author_id", authorId);
        boolean interest = interestMapper.exists(new QueryWrapper<InterestDO>().allEq(queryMap));

        // 先根据作者id得到paperId集合
        List<Integer> paperIds = new ArrayList<>();
        List<WorkDO> workRelations = workMapper.selectList(new QueryWrapper<WorkDO>().eq("author_id", authorId));
        for (WorkDO temp : workRelations) {
            paperIds.add(temp.getPaperId());
        }

        // 根据论文id得到论文DO集合
        List<AuthorPublicationDTO> authorPublicationDTOS = new ArrayList<>();

        // 调用API获取被引量，用array数组定义防止API调用失败时list空指针异常，并导致全部数据获取失败
        int[] citationCountArr = new int[workRelations.size()];
        // 设置后面POST请求的JSON请求体
        String jsonBody = "{\"ids\":[";
        for (int i = 0; i < workRelations.size(); i++) {
            String arxivId = getArxivIdFromPaperId(workRelations.get(i).getPaperId());
            jsonBody = jsonBody+"\"ARXIV:"+arxivId+"\",";
        }
        // 设置POST请求的URL
        String url = "https://api.semanticscholar.org/graph/v1/paper/batch?fields=citationCount";
        // 去掉最后一个循环的逗号
        jsonBody = jsonBody.substring(0, jsonBody.length() - 1);
        jsonBody = jsonBody+"]}";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, headers);
        // 创建RestTemplate对象
        RestTemplate restTemplate = new RestTemplate();
        // 发送POST请求并获取响应
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
        // 获取状态码
        HttpStatus statusCode = responseEntity.getStatusCode();
        // **********无论是ids为空还是json结构不对服务器响应状态码都是400，只要通过判断状态码为200就可以
        if (statusCode == HttpStatus.OK) {
            String responseBody = responseEntity.getBody();
            System.out.println("**********post:"+responseBody);
            // 使用 FastJSON 解析 JSON 数组
            JSONArray publicationArray = JSON.parseArray(responseBody);
            // 遍历数组，获取每个元素中的值
            for (int i = 0; i < publicationArray.size(); i++) {
                JSONObject publication = publicationArray.getJSONObject(i);
                citationCountArr[i] = publication.getInteger("citationCount");
            }
        }

        // 根据作者发表论文的分类、标题为基础数据，再利用YAKE分析其研究兴趣
        StringBuffer authorInterest = new StringBuffer();
        // 创建一个映射，将分类的简称和全称一一对应
        HashMap<String, String> catMap = new HashMap<>();
        catMap.put("cs.AI", "Artificial Intelligence of Computer Science");
        catMap.put("cs.AR", "Hardware Architecture of Computer Science");
        catMap.put("cs.CC", "Computational Complexity of Computer Science");
        catMap.put("cs.CE", "Computational Engineering, Finance, and Science of Computer Science");
        catMap.put("cs.CG", "Computational Geometry of Computer Science");
        catMap.put("cs.CL", "Computation and Language of Computer Science");
        catMap.put("cs.CR", "Cryptography and Security of Computer Science");
        catMap.put("cs.CV", "Computer Vision and Pattern Recognition of Computer Science");
        catMap.put("cs.CY", "Computers and Society of Computer Science");
        catMap.put("cs.DB", "Databases in Computer Science of Computer Science");
        catMap.put("cs.DC", "Distributed, Parallel, and Cluster Computing in Computer Science of Computer Science");
        catMap.put("cs.DL", "Digital Libraries of Computer Science");
        catMap.put("cs.DM", "Discrete Mathematics of Computer Science");
        catMap.put("cs.DS", "Data Structures and Algorithms of Computer Science");
        catMap.put("cs.ET", "Emerging Technologies of Computer Science");
        catMap.put("cs.FL", "Formal Languages and Automata Theory of Computer Science");
        catMap.put("cs.GL", "General Literature of Computer Science");
        catMap.put("cs.GR", "Graphics of Computer Science");
        catMap.put("cs.GT", "Computer Science and Game Theory of Computer Science");
        catMap.put("cs.HC", "Human-Computer Interaction of Computer Science");
        catMap.put("cs.IR", "Information Retrieval of Computer Science");
        catMap.put("cs.IT", "Information Theory of Computer Science");
        catMap.put("cs.LG", "Machine Learning of Computer Science");
        catMap.put("cs.LO", "Logic in Computer Science of Computer Science");
        catMap.put("cs.MA", "Multiagent Systems of Computer Science");
        catMap.put("cs.MM", "Multimedia of Computer Science");
        catMap.put("cs.MS", "Mathematical Software of Computer Science");
        catMap.put("cs.NA", "Numerical Analysis of Computer Science");
        catMap.put("cs.NE", "Neural and Evolutionary Computing of Computer Science");
        catMap.put("cs.NI", "Networking and Internet Architecture of Computer Science");
        catMap.put("cs.OH", "Other Computer Science of Computer Science");
        catMap.put("cs.OS", "Operating Systems of Computer Science");
        catMap.put("cs.PF", "Performance of Computer Science");
        catMap.put("cs.PL", "Programming Languages of Computer Science");
        catMap.put("cs.RO", "Robotics of Computer Science");
        catMap.put("cs.SC", "Symbolic Computation of Computer Science");
        catMap.put("cs.SD", "Sound of Computer Science");
        catMap.put("cs.SE", "Software Engineering of Computer Science");
        catMap.put("cs.SI", "Social and Information Networks of Computer Science");
        catMap.put("cs.SY", "Systems and Control of Computer Science");
        catMap.put("econ.EM", "Econometrics of Econometrics");
        catMap.put("econ.GN", "General Economics of Econometrics");
        catMap.put("econ.TH", "Theoretical Economics of Econometrics");
        catMap.put("eess.AS", "Audio and Speech Processing of Electrical Engineering and Systems Science");
        catMap.put("eess.IV", "Image and Video Processing of Electrical Engineering and Systems Science");
        catMap.put("eess.SP", "Signal Processing of Electrical Engineering and Systems Science");
        catMap.put("eess.SY", "Systems and Control of Electrical Engineering and Systems Science");
        catMap.put("math.AC", "Commutative Algebra of Mathematics");
        catMap.put("math.AG", "Algebraic Geometry of Mathematics");
        catMap.put("math.AP", "Analysis of PDEs of Mathematics");
        catMap.put("math.AT", "Algebraic Topology of Mathematics");
        catMap.put("math.CA", "Classical Analysis and ODEs of Mathematics");
        catMap.put("math.CO", "Combinatorics of Mathematics");
        catMap.put("math.CT", "Category Theory of Mathematics");
        catMap.put("math.CV", "Complex Variables of Mathematics");
        catMap.put("math.DG", "Differential Geometry of Mathematics");
        catMap.put("math.DS", "Dynamical Systems of Mathematics");
        catMap.put("math.FA", "Functional Analysis of Mathematics");
        catMap.put("math.GM", "General Mathematics of Mathematics");
        catMap.put("math.GN", "General Topology of Mathematics");
        catMap.put("math.GR", "Group Theory of Mathematics");
        catMap.put("math.GT", "Geometric Topology of Mathematics");
        catMap.put("math.HO", "History and Overview of Mathematics");
        catMap.put("math.IT", "Information Theory of Mathematics");
        catMap.put("math.KT", "K-Theory and Homology of Mathematics");
        catMap.put("math.LO", "Logic of Mathematics");
        catMap.put("math.MG", "Metric Geometry of Mathematics");
        catMap.put("math.MP", "Mathematical Physics of Mathematics");
        catMap.put("math.NA", "Numerical Analysis of Mathematics");
        catMap.put("math.NT", "Number Theory of Mathematics");
        catMap.put("math.OA", "Operator Algebras of Mathematics");
        catMap.put("math.OC", "Optimization and Control of Mathematics");
        catMap.put("math.PR", "Probability of Mathematics");
        catMap.put("math.QA", "Quantum Algebra of Mathematics");
        catMap.put("math.RA", "Rings and Algebras of Mathematics");
        catMap.put("math.RT", "Representation Theory of Mathematics");
        catMap.put("math.SG", "Symplectic Geometry of Mathematics");
        catMap.put("math.SP", "Spectral Theory of Mathematics");
        catMap.put("math.ST", "Statistics Theory of Mathematics");
        catMap.put("astro-ph.CO", "Cosmology and Nongalactic Astrophysics of Astrophysics in Physics");
        catMap.put("astro-ph.EP", "Earth and Planetary Astrophysics of Astrophysics in Physics");
        catMap.put("astro-ph.GA", "Astrophysics of Galaxies of Astrophysics in Physics");
        catMap.put("astro-ph.HE", "High Energy Astrophysical Phenomena of Astrophysics in Physics");
        catMap.put("astro-ph.IM", "Instrumentation and Methods for Astrophysics of Astrophysics in Physics");
        catMap.put("astro-ph.SR", "Solar and Stellar Astrophysics of Astrophysics in Physics");
        catMap.put("cond-mat.dis-nn", "Disordered Systems and Neural Networks of Condensed matter in Physics");
        catMap.put("cond-mat.mes-hall", "Mesoscale and Nanoscale Physics of Condensed matter in Physics");
        catMap.put("cond-mat.mtrl-sci", "Materials Science of Condensed Matter in Physics");
        catMap.put("cond-mat.other", "Other Condensed Matter of Condensed Matter in Physics");
        catMap.put("cond-mat.quant-gas", "Quantum Gases of Condensed Matter in Physics");
        catMap.put("cond-mat.soft", "Soft Condensed Matter of Condensed Matter in Physics");
        catMap.put("cond-mat.stat-mech", "Statistical Mechanics of Condensed Matter in Physics");
        catMap.put("cond-mat.str-el", "Strongly Correlated Electrons of Condensed Matter in Physics");
        catMap.put("cond-mat.supr-con", "Superconductivity of Condensed Matter in Physics");
        catMap.put("gr-qc", "General Relativity and Quantum Cosmology in Physics");
        catMap.put("hep-ex", "High Energy Physics - Experiment in Physics");
        catMap.put("hep-lat", "High Energy Physics - Lattice in Physics");
        catMap.put("hep-ph", "High Energy Physics - Phenomenology in Physics");
        catMap.put("hep-th", "High Energy Physics - Theory in Physics");
        catMap.put("math-ph", "Mathematical Physics in Physics");
        catMap.put("nlin.AO", "Adaptation and Self-Organizing Systems of Nonlinear Sciences in Physics");
        catMap.put("nlin.CD", "Chaotic Dynamics of Nonlinear Sciences in Physics");
        catMap.put("nlin.CG", "Cellular Automata and Lattice Gases of Nonlinear Sciences in Physics");
        catMap.put("nlin.PS", "Pattern Formation and Solitons of Nonlinear Sciences in Physics");
        catMap.put("nlin.SI", "Exactly Solvable and Integrable Systems of Nonlinear Sciences in Physics");
        catMap.put("nucl-ex", "Nuclear Experiment in Physics");
        catMap.put("nucl-th", "Nuclear Theory in Physics");
        catMap.put("physics.acc-ph", "Accelerator Physics in Physics");
        catMap.put("physics.ao-ph", "Atmospheric and Oceanic Physics in Physics");
        catMap.put("physics.app-ph", "Applied Physics in Physics");
        catMap.put("physics.atm-clus", "Atomic and Molecular Clusters in Physics");
        catMap.put("physics.atom-ph", "Atomic Physics in Physics");
        catMap.put("physics.bio-ph", "Biological Physics in Physics");
        catMap.put("physics.chem-ph", "Chemical Physics in Physics");
        catMap.put("physics.class-ph", "Classical Physics in Physics");
        catMap.put("physics.comp-ph", "Computational Physics in Physics");
        catMap.put("physics.data-an", "Data Analysis, Statistics and Probability in Physics");
        catMap.put("physics.ed-ph", "Physics Education in Physics");
        catMap.put("physics.flu-dyn", "Fluid Dynamics in Physics");
        catMap.put("physics.gen-ph", "General Physics in Physics");
        catMap.put("physics.geo-ph", "Geophysics in Physics");
        catMap.put("physics.hist-ph", "History and Philosophy of Physics in Physics");
        catMap.put("physics.ins-det", "Instrumentation and Detectors in Physics");
        catMap.put("physics.med-ph", "Medical Physics in Physics");
        catMap.put("physics.optics", "Optics in Physics");
        catMap.put("physics.plasm-ph", "Plasma Physics in Physics");
        catMap.put("physics.pop-ph", "Popular Physics in Physics");
        catMap.put("physics.soc-ph", "Physics and Society in Physics");
        catMap.put("physics.space-ph", "Space Physics in Physics");
        catMap.put("quant-ph", "Quantum Physics in Physics");
        catMap.put("q-bio.BM", "Biomolecules of Quantitative Biology");
        catMap.put("q-bio.CB", "Cell Behavior of Quantitative Biology");
        catMap.put("q-bio.GN", "Genomics of Quantitative Biology");
        catMap.put("q-bio.MN", "Molecular Networks of Quantitative Biology");
        catMap.put("q-bio.NC", "Neurons and Cognition of Quantitative Biology");
        catMap.put("q-bio.OT", "Other Quantitative Biology of Quantitative Biology");
        catMap.put("q-bio.PE", "Populations and Evolution of Quantitative Biology");
        catMap.put("q-bio.QM", "Quantitative Methods of Quantitative Biology");
        catMap.put("q-bio.SC", "Subcellular Processes of Quantitative Biology");
        catMap.put("q-bio.TO", "Tissues and Organs of Quantitative Biology");
        catMap.put("q-fin.CP", "Computational Finance of Quantitative Finance");
        catMap.put("q-fin.EC", "Economics of Quantitative Finance");
        catMap.put("q-fin.GN", "General Finance of Quantitative Finance");
        catMap.put("q-fin.MF", "Mathematical Finance of Quantitative Finance");
        catMap.put("q-fin.PM", "Portfolio Management of Quantitative Finance");
        catMap.put("q-fin.PR", "Pricing of Securities of Quantitative Finance");
        catMap.put("q-fin.RM", "Risk Management of Quantitative Finance");
        catMap.put("q-fin.ST", "Statistical Finance of Quantitative Finance");
        catMap.put("q-fin.TR", "Trading and Market Microstructure of Quantitative Finance");
        catMap.put("stat.AP", "Applications of Statistics");
        catMap.put("stat.CO", "Computation of Statistics");
        catMap.put("stat.ME", "Methodology of Statistics");
        catMap.put("stat.ML", "Machine Learning of Statistics");
        catMap.put("stat.OT", "Other Statistics of Statistics");
        catMap.put("stat.TH", "Statistics Theory of Statistics");

        for (int i = 0; i < workRelations.size(); i++) {
            PaperDO paperDO = baseMapper.selectById(workRelations.get(i).getPaperId());

            // 将特征数据拼接成一个字符串，根据YAKE原理，分类比较重要放前面，标题放后面
            String[] cats = paperDO.getCategories().split(" ");
            // 遍历分类简称数组，转换为全称
            for (String cat : cats) {
                // 检查映射中是否存在对应的全称
                if (catMap.containsKey(cat)) {
                    String catDetail = catMap.get(cat);
                    authorInterest.append(catDetail).append(", ");
                } else {
                    authorInterest.append(cat).append(", ");
                }
            }
            authorInterest.append(paperDO.getTitle()).append(". ");

            PaperDTO paperDTO = convertToDTO(paperDO, userId);
            AuthorPublicationDTO authorPublicationDTO = new AuthorPublicationDTO(workRelations.get(i).getPaperId(), paperDTO.getTitle(), paperDTO.getAuthors(), paperDTO.getUpdate_date(), paperDO.getCategories().split(" "), paperDO.getUrl(), citationCountArr[i]);
            authorPublicationDTOS.add(authorPublicationDTO);
        }

        // 创建一个比较器，根据 update_date 字段降序排列
        Comparator<AuthorPublicationDTO> comparator = (paper1, paper2) -> paper2.getUpdate_date().compareTo(paper1.getUpdate_date());
        // 使用 List.sort() 方法进行排序
        authorPublicationDTOS.sort(comparator);

        AuthorInfoDTO authorInfoDTO = new AuthorInfoDTO();
        authorInfoDTO.setAuthor(authorDTO);
        authorInfoDTO.setPaperList(authorPublicationDTOS);
        authorInfoDTO.setInterest(interest);

        // 调用py生成研究兴趣云图
        try {
            String exe = "D:\\Python\\venv\\Scripts\\python.exe";
            String py = "D:\\Python\\theOne\\get_authorInterest.py";
            String [] my_args = new String[] {exe, py, authorInterest.toString()};
            Process proc = Runtime.getRuntime().exec(my_args);//执行脚本
            proc.waitFor();
        } catch (IOException | InterruptedException e) {
            return new HttpResponse<>(new StatusDTO(1, "研究兴趣云图生成失败"), authorInfoDTO);
        }

        return new HttpResponse<>(new StatusDTO(Constant.SUC_CODE, Constant.SUC_GET_AUTHOR_INFO), authorInfoDTO);
    }

    // 获取作者信息
//    public HttpResponse<AuthorInfoDTO> getAuthorInfo(AuthorInfoParam param, String token) {
//        int authorId = param.getAuthorId();
//        int userId = TokenParser.parse(token);
//        AuthorDO authorDO = authorMapper.selectById(authorId);
////        定义柱状图列表
//        LinkedList<SingleDTO> indexInfo = new LinkedList<>();
////        获取引用数
//        CiteInfoDTO citeInfoDTO = new CiteInfoDTO();
//        if (authorDO.getTotal() != null) {
//            String[] citeInfo = authorDO.getTotal().split(" ");
//            citeInfoDTO.setCite_num(Integer.valueOf(citeInfo[0]));
//            citeInfoDTO.setRecent_cite_num(Integer.valueOf(citeInfo[1]));
//            citeInfoDTO.setH_index(Integer.valueOf(citeInfo[2]));
//            citeInfoDTO.setRecent_h_index(Integer.valueOf(citeInfo[3]));
//            citeInfoDTO.setI_index(Integer.valueOf(citeInfo[4]));
//            citeInfoDTO.setRecent_i_index(Integer.valueOf(citeInfo[5]));
//        }
////获取柱状图数据
//        if (authorDO.getSingle() != null) {
//            String[] single = authorDO.getSingle().split(" ");
//            int i = 0;
//
//            for (int len = single.length - 1; len >= 0; len--) {
//                int year = 2023;
//                year = year - i;
//                SingleDTO singleDTO = new SingleDTO(String.valueOf(year), Integer.valueOf(single[len]));
//                indexInfo.addFirst(singleDTO);
//                i++;
//            }
//        }
////        判空
//        if (authorDO == null) {
//            return new HttpResponse<>(new StatusDTO(1, "作者id不存在"), null);
//        } else {
//            // 要根据作者id得到他的论文DTO集合
//            // 先根据作者id得到创作关系集合
//            List<Integer> a = new ArrayList<>();
//            List<WorkDO> workRelations = workMapper.selectList(new QueryWrapper<WorkDO>().eq("author_id", authorId));
//            for (WorkDO temp : workRelations) {
//                a.add(temp.getPaperId());
//            }
////            获取合著作者
//            Set<AuthorDTO> authorlist = new HashSet<>();
//            List<WorkDO> authorId1 = workMapper.selectList(new QueryWrapper<WorkDO>().in("paper_id", a));
//            int count = 0;
//            for (WorkDO b : authorId1) {
//                if (b.getAuthorId() != authorId && count < 2) {
//                    AuthorDO authorDO1 = authorMapper.selectById(b.getAuthorId());
//                    AuthorDTO authorDTO = new AuthorDTO(authorDO1.getAuthorId(), authorDO1.getAuthorName(), null);
//                    authorlist.add(authorDTO);
//                    count++;
//                }
//            }
//            // 根据论文id得到论文DO集合
////            List<PaperDTO> paperDTOS = workRelations.stream()
////                    .map(workRelation -> getPaperDTOById(workRelation.getPaperId(), userId))
////                    .collect(Collectors.toList());
//            List<PaperAllDo> paperAllDos = new ArrayList<>();
//            for (WorkDO temp : workRelations) {
//                // 获取最新版本
//                QueryWrapper<VersionDO> queryWrapper = new QueryWrapper<>();
//                queryWrapper.eq("paper_id", temp.getPaperId());
//                List<VersionDO> versionDO = versionsMapper.selectList(queryWrapper);
////                获取长度
//                int len = versionDO.size();
////取出最大的版本号
//                String version = versionDO.get(0).getVersion();
//                for (VersionDO t : versionDO) {
//
//                    int result = t.getVersion().compareTo(version);
//                    if (result > 0) {
//                        version = t.getVersion();
//                    }
//                }
//
//                PaperDO paperDO = baseMapper.selectById(temp.getPaperId());
//
//                PaperDTO paperDTO = convertToDTO(paperDO, userId);
//                paperDTO.setPaper_abstract(paperDO.getPaperAbstract());
//                PaperAllDo paperAllDo = new PaperAllDo(temp.getPaperId(), paperDTO.getTitle(), paperDTO.getAuthors(), paperDTO.getUpdate_date(), paperDTO.getPaper_abstract(), paperDO.getJournalRef(),null, paperDO.getCategories().split(" "), paperDO.getUrl(), version, paperDO.getDoi(), false);
//                paperAllDos.add(paperAllDo);
//            }
//            boolean interest = false;
//            UserDO userDO = userMapper.selectById(userId);
////            if (userDO.getFollowingList() != null) {
////                for (String tempInterest :
////                        userDO.getFollowingList().split(",")) {
////                    if (authorId == Integer.valueOf(tempInterest)) {
////                        interest = true;
////                    }
////                }
////            }
//            AuthorInfoDTO authorInfoDTO = new AuthorInfoDTO();
//            AuthorDTO authorDTO = new AuthorDTO(authorDO.getAuthorId(), authorDO.getAuthorName(), null);
//            authorInfoDTO.setAuthor(authorDTO);
//            authorInfoDTO.setPaperList(paperAllDos);
//            authorInfoDTO.setAuthorList(authorlist);
//            authorInfoDTO.setCiteInfo(citeInfoDTO);
//            authorInfoDTO.setIndexInfo(indexInfo);
//            authorInfoDTO.setInterest(interest);
//            return new HttpResponse<>(new StatusDTO(Constant.SUC_CODE, Constant.SUC_GET_AUTHOR_INFO), authorInfoDTO);
//        }
//    }

    // 记录论文浏览历史
    public HttpResponse addBrowsing(PaperIdParam param, String token) {
        int userId = TokenParser.parse(token);
        int paperId = param.getPaperId();

        HashMap<String, Integer> queryMap = new HashMap<>(2);
        queryMap.put("user_id", userId);
        queryMap.put("paper_id", paperId);
        QueryWrapper<BrowsingDO> queryWrapper = new QueryWrapper<BrowsingDO>().allEq(queryMap);
        boolean browsing = browsingMapper.exists(queryWrapper);

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = now.format(formatter);

        if (browsing) {
            // 曾浏览过该论文时，只需修改时间
            BrowsingDO browsingDO = browsingMapper.selectOne(queryWrapper);
            browsingDO.setBrowsingTime(formattedDateTime);
            browsingMapper.update(browsingDO, queryWrapper);
        } else {
            // 第一次浏览直接记录信息
            BrowsingDO browsingDO = new BrowsingDO(0, userId, paperId, formattedDateTime);
            browsingMapper.insert(browsingDO);
        }
        return new HttpResponse(new StatusDTO(0, "记录论文浏览历史成功"), null);
    }

    // 删除浏览记录
    public HttpResponse deleteBrowsing(PaperIdParam param, String token) {
        int userId = TokenParser.parse(token);
        int paperId = param.getPaperId();

        HashMap<String, Integer> queryMap = new HashMap<>(2);
        queryMap.put("user_id", userId);
        queryMap.put("paper_id", paperId);
        browsingMapper.delete(new QueryWrapper<BrowsingDO>().allEq(queryMap));

        return new HttpResponse(new StatusDTO(0, "删除浏览记录成功"), null);
    }

    // 修改收藏状态
    public HttpResponse modifyFavorite(PaperIdParam param, String token) {
        int userId = TokenParser.parse(token);
        int paperId = param.getPaperId();

        if (isFavorite(userId, paperId)) {
            // 已被收藏
            HashMap<String, Integer> queryMap = new HashMap<>(2);
            queryMap.put("user_id", userId);
            queryMap.put("paper_id", paperId);
            favoriteMapper.delete(new QueryWrapper<FavoriteDO>().allEq(queryMap));
        } else {
            // 获取当前日期和时间
            LocalDateTime now = LocalDateTime.now();
            // 定义日期时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            // 格式化日期时间为字符串
            String formattedDateTime = now.format(formatter);
            FavoriteDO favoriteDO = new FavoriteDO(0, userId, paperId, formattedDateTime);
            favoriteMapper.insert(favoriteDO);
        }
        return new HttpResponse(new StatusDTO(0, "修改收藏状态成功"), null);
    }

    // 获取论文详情
    public HttpResponse<DataPaperDTO> getPaperDetail(PaperIdParam param, String token) {
        Integer paperId = param.getPaperId();
        if (!existPaper(paperId)) {
            return new HttpResponse<>(new StatusDTO(1, "论文id不存在"), null);
        }
        Integer userId = TokenParser.parse(token);
        PaperDetailDTO paperDetailDTO = getPaperDetailById(paperId, userId);
        return new HttpResponse<>(
                new StatusDTO(Constant.SUC_CODE, Constant.SUC_FIND_PAPER_INFO),
                new DataPaperDTO(paperDetailDTO));
    }

    /**
     * 根据论文id返回论文基本信息
     *
     * @param paperId 论文id
     * @param userId
     * @return 返回PaperDTO, 包含作者和基本信息
     */
    public PaperDTO getPaperDTOById(Integer paperId, Integer userId) {
        PaperDO paperDO = baseMapper.selectById(paperId);
        return convertToDTO(paperDO, userId);
    }

    @Override
    public HttpResponse<List> gettagInfo(String token) {

        List<TagDO> tagDOS = tagsMapper.selectList(null);
        List<TagDTO> list = new ArrayList<>();
        for (TagDO tagDO :
                tagDOS) {
            TagDTO tagDTO = new TagDTO(tagDO.getLabel());
            list.add(tagDTO);
        }
        return new HttpResponse<>(new StatusDTO(0, "标签信息获取成功"), list);
    }

    @Override
    public HttpResponse<List> searchTag(PaperSearchParam param, String token) {
        String query = param.getQuery();
        QueryWrapper<TagDO> qw = new QueryWrapper<>();
        qw.like("label", query);
        List<TagDO> tagDOS = tagsMapper.selectList(qw);
        List<TagDTO> list = new ArrayList<>();
        for (TagDO tagDO :
                tagDOS) {
            TagDTO tagDTO = new TagDTO(tagDO.getLabel());
            list.add(tagDTO);
        }
        return new HttpResponse<>(new StatusDTO(0, "标签信息查找成功"), list);
    }

    @Override
    public HttpResponse<List> getVersions(PaperIdParam param, String token) {
        Integer id = param.getPaperId();
        QueryWrapper<VersionDO> queryWrapper = new QueryWrapper<>();
// 设置查询条件
        queryWrapper.eq("paper_id", id);
        List<VersionDO> versionDO = versionsMapper.selectList(queryWrapper);
        List<VersionDTO> versionDTOS = new ArrayList<>();
        for (VersionDO temp : versionDO) {
            VersionDTO a = new VersionDTO(temp.getVersion(), temp.getCreated());
            versionDTOS.add(a);

        }
        return new HttpResponse<>(new StatusDTO(0, "版本线查找成功"), versionDTOS);
    }

    /**
     * 根据论文DO获取DTO，包含作者
     *
     * @param paper  论文DO对象
     * @param userId
     * @return 论文DTO对象
     */
    public PaperDTO convertToDTO(PaperDO paper, Integer userId) {
        // 将paperDO转成paperDTO
        PaperDTO paperDTO = PaperConverter.Instance.paperDOToDto(paper);

        int paperId = paper.getPaperId();
        // AuthorService.getAuthorDTOsByPaperId(int paperId);
        List<AuthorDTO> authorDTOS = getAuthorsByPaperId(paperId);
        paperDTO.setAuthors(authorDTOS);

        // TODO 可以优化，查找收藏的论文时可以略去这个查询
        // 得到论文是否被收藏
        // boolean isFavorite = favoriteService.isFavorite(userId, paperId);
        paperDTO.setFavorite(isFavorite(userId, paperId));
        return paperDTO;

    }

    /**
     * 根据论文id得到论文详情
     *
     * @param paperId
     * @param userId
     * @return
     */
    public PaperDetailDTO getPaperDetailById(Integer paperId, Integer userId) {
        PaperDO paperDO = baseMapper.selectById(paperId);
        return convertToDetailDTO(paperDO, userId);
    }

    /**
     * 根据论文DO获取论文详情，解析作者和学科
     *
     * @param paperDO
     * @param userId
     * @return
     */
    public PaperDetailDTO convertToDetailDTO(PaperDO paperDO, Integer userId) {
        PaperConverter converter = PaperConverter.Instance;
        PaperDetailDTO paperDetailDTO = converter.paperDOToDetail(paperDO);
        Integer paperId = paperDO.getPaperId();
        paperDetailDTO.setAuthors(getAuthorsByPaperId(paperId));
        paperDetailDTO.setFavorite(isFavorite(userId, paperId));
        paperDetailDTO.setCategories(Arrays.asList(paperDO.getCategories().split(" ")));
        return paperDetailDTO;
    }

    /**
     * 判断论文id是否存在
     *
     * @param paperId
     * @return
     */
    public boolean existPaper(Integer paperId) {
        return query().eq("paper_id", paperId).exists();
    }

    /**
     * 根据论文id集合获取论文集合
     *
     * @param paperIds 论文id集合
     * @param userId
     * @return 论文基本信息集合
     */
    public List<PaperDTO> getPaperDTOsByBatchId(List<Integer> paperIds, Integer userId) {
        return baseMapper.selectBatchIds(paperIds)
                .stream()
                .map(paper -> convertToDTO(paper, userId))
                .collect(Collectors.toList());
    }

    /**
     * 根据论文id获得该论文的全部作者集合
     *
     * @param paperId
     * @return
     */
    public List<AuthorDTO> getAuthorsByPaperId(Integer paperId) {
        // 要根据论文id得到作者DTO集合
        // 先根据论文id得到创作关系集合
        List<WorkDO> workRelationList = workMapper.selectList(new QueryWrapper<WorkDO>().eq("paper_id", paperId));
        // 根据创作关系得到作者集合
        List<AuthorDO> authors = workRelationList.stream()
                .map(workRelation -> authorMapper.selectById(workRelation.getAuthorId()))
                .collect(Collectors.toList());
        // 把authorDO映射成AuthorDTO
        List<AuthorDTO> authorDTOs = authors.stream().map(authorDO -> {
            AuthorConverter instance = AuthorConverter.INSTANCE;
            return instance.authorDoToDto(authorDO);
        }).collect(Collectors.toList());

        return authorDTOs;
    }

    /**
     * 判断该论文是否被当前用户收藏
     * TODO 我在想这里是不是可以返回收藏id
     *
     * @param userId
     * @param paperId
     * @return 被收藏则返回id, 否则返回-1
     */
    public boolean isFavorite(Integer userId, Integer paperId) {
        HashMap<String, Integer> queryMap = new HashMap<>(2);
        queryMap.put("user_id", userId);
        queryMap.put("paper_id", paperId);
        return favoriteMapper.exists(new QueryWrapper<FavoriteDO>().allEq(queryMap));
    }

    /**
     * 根据用户id获取浏览的论文基本对象的分页集合
     *
     * @param userId
     * @param maxLength
     * @param offset
     * @return 返回论文的页对象
     */
    public IPage<PaperBrowsingDTO> getBrowsingPapersPage(int userId, int maxLength, int offset) {
        // 分页信息
        IPage<BrowsingDO> pageInfo = PageParser.getPage(maxLength, offset);
        QueryWrapper<BrowsingDO> browsingQueryWrapper = new QueryWrapper<>();
        // 得到浏览关系集合
        IPage<BrowsingDO> browsingRelationsPage = browsingMapper.
                selectPage(pageInfo, browsingQueryWrapper.eq("user_id", userId));
        // 使用convert方法将浏览关系列表转换为PaperBrowsingDTO列表
        IPage<PaperBrowsingDTO> browsingPapersPage = browsingRelationsPage.convert(browsingDO -> {
            // 获取收藏时间
            String browsingTime = browsingDO.getBrowsingTime();
            // 获取论文DTO对象
            PaperDTO paperDTO = getPaperDTOById(browsingDO.getPaperId(), userId);
            // 创建PaperFavoriteDTO对象并设置相关信息
            PaperBrowsingDTO paperBrowsingDTO = new PaperBrowsingDTO();
            paperBrowsingDTO.setPaper_id(paperDTO.getPaper_id());
            paperBrowsingDTO.setTitle(paperDTO.getTitle());
            paperBrowsingDTO.setAuthors(paperDTO.getAuthors());
            paperBrowsingDTO.setUpdate_date(paperDTO.getUpdate_date());
            paperBrowsingDTO.setBrowsing_time(browsingTime);

            return paperBrowsingDTO;
        });

        return browsingPapersPage;
    }

    /**
     * 根据用户id获得收藏的论文基本对象的分页集合
     *
     * @param userId
     * @param maxLength
     * @param offset
     * @return 返回论文的页对象
     */
    public IPage<PaperFavoriteDTO> getFavoritePapersPage(int userId, int maxLength, int offset) {
        // 分页信息
        IPage<FavoriteDO> pageInfo = PageParser.getPage(maxLength, offset);
        QueryWrapper<FavoriteDO> favoriteQueryWrapper = new QueryWrapper<>();
        // 得到收藏关系集合
        IPage<FavoriteDO> favoriteRelationsPage = favoriteMapper.
                selectPage(pageInfo, favoriteQueryWrapper.eq("user_id", userId));
        // 根据收藏的论文id得到论文DTO集合
//        IPage<PaperDTO> favoritePapersPage = favoriteRelationsPage.
//                convert(favoriteRelation -> this.getPaperDTOById(favoriteRelation.getPaperId(), userId));

        // 使用convert方法将收藏关系列表转换为PaperFavoriteDTO列表
        IPage<PaperFavoriteDTO> favoritePapersPage = favoriteRelationsPage.convert(favoriteDO -> {
            // 获取收藏时间
            String favoriteTime = favoriteDO.getFavoriteTime();
            // 获取论文DTO对象
            PaperDTO paperDTO = getPaperDTOById(favoriteDO.getPaperId(), userId);

            // 创建PaperFavoriteDTO对象并设置相关信息
            PaperFavoriteDTO paperFavoriteDTO = new PaperFavoriteDTO();
            paperFavoriteDTO.setPaper_id(paperDTO.getPaper_id());
            paperFavoriteDTO.setTitle(paperDTO.getTitle());
            paperFavoriteDTO.setAuthors(paperDTO.getAuthors());
            paperFavoriteDTO.setUpdate_date(paperDTO.getUpdate_date());
            paperFavoriteDTO.setFavorite(paperDTO.isFavorite());
            paperFavoriteDTO.setFavorite_time(favoriteTime);

            return paperFavoriteDTO;
        });

        return favoritePapersPage;
    }
}
